home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / bash_114.zip / bash-1.14.2 / nojobs.c < prev    next >
C/C++ Source or Header  |  1994-06-20  |  15KB  |  644 lines

  1. /* The thing that makes children, remembers them, and contains wait loops. */
  2.  
  3. /* This file works under BSD, System V, minix, and Posix systems. */
  4.  
  5. /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
  6.  
  7.    This file is part of GNU Bash, the Bourne Again SHell.
  8.  
  9.    Bash is free software; you can redistribute it and/or modify it under
  10.    the terms of the GNU General Public License as published by the Free
  11.    Software Foundation; either version 1, or (at your option) any later
  12.    version.
  13.  
  14.    Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  15.    WARRANTY; without even the implied warranty of MERCHANTABILITY or
  16.    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  17.    for more details.
  18.  
  19.    You should have received a copy of the GNU General Public License along
  20.    with Bash; see the file COPYING.  If not, write to the Free Software
  21.    Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  22.  
  23. #include <stdio.h>
  24. #include "bashtypes.h"
  25. #include <signal.h>
  26. #include <setjmp.h>
  27. #include <errno.h>
  28.  
  29. #include "config.h"
  30. #include "command.h"
  31. #include "general.h"
  32. #include "filecntl.h"
  33. #include "jobs.h"
  34. #include "externs.h"
  35.  
  36. #if defined (BUFFERED_INPUT)
  37. #  include "input.h"
  38. #endif
  39.  
  40. #if !defined (USG) && !defined (_POSIX_VERSION)
  41. #  include <sgtty.h>
  42. #else
  43. #  if defined (_POSIX_VERSION)
  44. #    include <termios.h>
  45. #  else
  46. #    include <termio.h>
  47. #    if !defined (AIXRT)
  48. #      include <sys/ttold.h>
  49. #    endif /* !AIXRT */
  50. #  endif /* !POSIX_VERSION */
  51. #endif /* USG && _POSIX_VERSION */
  52.  
  53. #if !defined (SIGABRT)
  54. #  define SIGABRT SIGIOT
  55. #endif /* !SIGABRT */
  56.  
  57. #if defined (USG) || defined (_POSIX_VERSION)
  58. #  define killpg(pg, sig)        kill(-(pg),(sig))
  59. #endif /* USG || _POSIX_VERSION */
  60.  
  61. #if defined (USG)
  62. #  define siginterrupt(sig, code)
  63. #endif /* USG */
  64.  
  65. #if defined (_POSIX_VERSION)
  66. #  define WAITPID(pid, statusp, options) waitpid (pid, statusp, options)
  67. #else
  68. #  define WAITPID(pid, statusp, options) wait (statusp)
  69. #endif /* !_POSIX_VERSION */
  70.  
  71. #if !defined (errno)
  72. extern int errno;
  73. #endif /* !errno */
  74.  
  75. extern int interactive, interactive_shell, login_shell;
  76. extern int subshell_environment;
  77. extern int last_command_exit_value;
  78. #if defined (_POSIX_VERSION)
  79. extern sigset_t top_level_mask;
  80. #endif
  81.  
  82. pid_t last_made_pid = NO_PID;
  83. pid_t last_asynchronous_pid = NO_PID;
  84.  
  85. /* Call this when you start making children. */
  86. int already_making_children = 0;
  87.  
  88. #if defined (_POSIX_VERSION)
  89. static void reap_zombie_children ();
  90. #endif
  91.  
  92. struct proc_status {
  93.   pid_t pid;
  94.   int status;    /* Exit status of PID or 128 + fatal signal number */
  95. };
  96.  
  97. static struct proc_status *pid_list = (struct proc_status *)NULL;
  98. static int pid_list_size = 0;
  99.  
  100. #define PROC_BAD -1
  101. #define PROC_STILL_ALIVE -2
  102.  
  103. /* Allocate new, or grow existing PID_LIST. */
  104. static void
  105. alloc_pid_list ()
  106. {
  107.   register int i;
  108.   int old = pid_list_size;
  109.  
  110.   pid_list_size += 10;
  111.   pid_list = (struct proc_status *)
  112.     xrealloc (pid_list, pid_list_size * sizeof (struct proc_status));
  113.  
  114.   /* None of the newly allocated slots have process id's yet. */
  115.   for (i = old; i < pid_list_size; i++)
  116.     pid_list[i].pid = NO_PID;  
  117. }
  118.  
  119. /* Return the offset within the PID_LIST array of an empty slot.  This can
  120.    create new slots if all of the existing slots are taken. */
  121. static int
  122. find_proc_slot ()
  123. {
  124.   register int i;
  125.  
  126.   for (i = 0; i < pid_list_size; i++)
  127.     if (pid_list[i].pid == NO_PID)
  128.       return (i);
  129.  
  130.   if (i == pid_list_size)
  131.     alloc_pid_list ();
  132.  
  133.   return (i);
  134. }
  135.  
  136. /* Return the offset within the PID_LIST array of a slot containing PID,
  137.    or the value NO_PID if the pid wasn't found. */
  138. static int
  139. find_index_by_pid (pid)
  140.      pid_t pid;
  141. {
  142.   register int i;
  143.  
  144.   for (i = 0; i < pid_list_size; i++)
  145.     if (pid_list[i].pid == pid)
  146.       return (i);
  147.  
  148.   return (NO_PID);
  149. }
  150.  
  151. /* Return the status of PID as looked up in the PID_LIST array.  A
  152.    return value of PROC_BAD indicates that PID wasn't found. */
  153. static int
  154. find_status_by_pid (pid)
  155.      pid_t pid;
  156. {
  157.   int i;
  158.  
  159.   i = find_index_by_pid (pid);
  160.   if (i == NO_PID)
  161.     return (PROC_BAD);
  162.   return (pid_list[i].status);
  163. }
  164.  
  165. /* Give PID the status value STATUS in the PID_LIST array. */
  166. static void
  167. set_pid_status (pid, status)
  168.      pid_t pid;
  169.      WAIT status;
  170. {
  171.   int slot;
  172.  
  173.   slot = find_index_by_pid (pid);
  174.   if (slot == NO_PID)
  175.     return;
  176.  
  177.   if (WIFSIGNALED (status))
  178.     pid_list[slot].status = 128 + WTERMSIG (status);
  179.   else
  180.     pid_list[slot].status = WEXITSTATUS (status);
  181. }
  182.  
  183. static void
  184. add_pid (pid)
  185.      pid_t pid;
  186. {
  187.   int slot;
  188.  
  189.   slot = find_proc_slot ();
  190.   pid_list[slot].pid = pid;
  191.   pid_list[slot].status = PROC_STILL_ALIVE;
  192. }
  193.  
  194. int
  195. cleanup_dead_jobs ()
  196. {
  197.   register int i;
  198.  
  199. #if defined (_POSIX_VERSION)
  200.   reap_zombie_children ();
  201. #endif
  202.  
  203.   for (i = 0; i < pid_list_size; i++)
  204.     if (pid_list[i].status != PROC_STILL_ALIVE)
  205.       pid_list[i].pid = NO_PID;
  206. }
  207.  
  208. /* Initialize the job control mechanism, and set up the tty stuff. */
  209. initialize_jobs ()
  210. {
  211.   get_tty_state ();
  212. }
  213.  
  214. #if !defined (READLINE) && defined (TIOCGWINSZ) && defined (SIGWINCH)
  215. static SigHandler *old_winch;
  216.  
  217. static sighandler
  218. sigwinch_sighandler (sig)
  219.      int sig;
  220. {
  221.   struct winsize win;
  222.  
  223. #if defined (USG) && !defined (_POSIX_VERSION)
  224.   set_signal_handler (SIGWINCH, sigwinch_sighandler);
  225. #endif /* USG && !_POSIX_VERSION */
  226.   if ((ioctl (0, TIOCGWINSZ, &win) == 0) &&
  227.       win.ws_row > 0 && win.ws_col > 0)
  228.     set_lines_and_columns (win.ws_row, win.ws_col);
  229. }
  230. #endif /* !READLINE && TIOCGWINSZ && SIGWINCH */
  231.  
  232. /* Setup this shell to handle C-C, etc. */
  233. void
  234. initialize_job_signals ()
  235. {
  236.   set_signal_handler (SIGINT, sigint_sighandler);
  237. #if !defined (READLINE) && defined (TIOCGWINSZ) && defined (SIGWINCH)
  238.   set_signal_handler (SIGWINCH, sigwinch_sighandler);
  239. #endif /* !READLINE && TIOCGWINSZ && SIGWINCH */
  240.  
  241.   /* If this is a login shell we don't wish to be disturbed by
  242.      stop signals. */
  243.   if (login_shell)
  244.     {
  245. #if defined (SIGTSTP)
  246.       set_signal_handler (SIGTSTP, SIG_IGN);
  247.       set_signal_handler (SIGTTOU, SIG_IGN);
  248.       set_signal_handler (SIGTTIN, SIG_IGN);
  249. #endif
  250.     }
  251. }
  252.  
  253. #if defined (_POSIX_VERSION)
  254. /* Collect the status of all zombie children so that their system
  255.    resources can be deallocated. */
  256. static void
  257. reap_zombie_children ()
  258. {
  259. #if defined (WNOHANG)
  260.   pid_t pid;
  261.   WAIT status;
  262.  
  263.   while ((pid = waitpid (-1, (int *)&status, WNOHANG)) > 0)
  264.     set_pid_status (pid, status);
  265. #endif /* WNOHANG */
  266. }
  267. #endif /* _POSIX_VERSION */
  268.  
  269. /* Fork, handling errors.  Returns the pid of the newly made child, or 0.
  270.    COMMAND is just for remembering the name of the command; we don't do
  271.    anything else with it.  ASYNC_P says what to do with the tty.  If
  272.    non-zero, then don't give it away. */
  273. pid_t
  274. make_child (command, async_p)
  275.      char *command;
  276.      int async_p;
  277. {
  278.   pid_t pid;
  279. #if defined (_POSIX_VERSION)
  280.   int retry = 1;
  281. #endif /* _POSIX_VERSION */
  282.  
  283.   /* Discard saved memory. */
  284.   if (command)  
  285.     free (command);
  286.  
  287.   start_pipeline ();
  288.  
  289. #if defined (BUFFERED_INPUT)
  290.   /* If default_buffered_input is active, we are reading a script.  If
  291.      the command is asynchronous, we have already duplicated /dev/null
  292.      as fd 0, but have not changed the buffered stream corresponding to
  293.      the old fd 0.  We don't want to sync the stream in this case. */
  294.   if (default_buffered_input != -1 &&
  295.       (!async_p || default_buffered_input > 0))
  296.     sync_buffered_stream (default_buffered_input);
  297. #endif /* BUFFERED_INPUT */
  298.  
  299.   /* Create the child, handle severe errors. */
  300. #if defined (_POSIX_VERSION)
  301.   retry_fork:
  302. #endif /* _POSIX_VERSION */
  303.  
  304.   if ((pid = fork ()) < 0)
  305.     {
  306. #if defined (_POSIX_VERSION)
  307.       /* Posix systems with a non-blocking waitpid () system call available
  308.      get another chance after zombies are reaped. */
  309.       if (errno == EAGAIN && retry)
  310.     {
  311.       reap_zombie_children ();
  312.       retry = 0;
  313.       goto retry_fork;
  314.     }
  315. #endif /* _POSIX_VERSION */
  316.  
  317.       internal_error ("fork: %s", strerror (errno));
  318.  
  319.       throw_to_top_level ();
  320.     }
  321.  
  322.   if (pid == 0)
  323.     {
  324. #if defined (BUFFERED_INPUT)
  325.       if (default_buffered_input > 0)
  326.     {
  327.           close_buffered_fd (default_buffered_input);
  328.           default_buffered_input = bash_input.location.buffered_fd = -1;
  329.     }
  330. #endif /* BUFFERED_INPUT */
  331.  
  332. #if defined (_POSIX_VERSION)
  333.       /* Restore top-level signal mask. */
  334.       sigprocmask (SIG_SETMASK, &top_level_mask, (sigset_t *)NULL);
  335. #endif
  336.  
  337.       /* Ignore INT and QUIT in asynchronous children. */
  338.       if (async_p)
  339.     {
  340. #if 0
  341.       /* This now done by setup_async_signals (). */
  342.       set_signal_handler (SIGINT, SIG_IGN);
  343.       set_signal_handler (SIGQUIT, SIG_IGN);
  344. #endif
  345.       last_asynchronous_pid = getpid ();
  346.     }
  347.  
  348. #if defined (SIGTSTP)
  349.       set_signal_handler (SIGTSTP, SIG_DFL);
  350.       set_signal_handler (SIGTTIN, SIG_DFL);
  351.       set_signal_handler (SIGTTOU, SIG_DFL);
  352. #endif
  353.     }
  354.   else
  355.     {
  356.       /* In the parent. */
  357.  
  358.       last_made_pid = pid;
  359.  
  360.       if (async_p)
  361.     last_asynchronous_pid = pid;
  362.  
  363.       add_pid (pid);
  364.     }
  365.   return (pid);
  366. }
  367.  
  368. /* Wait for a single pid (PID) and return its exit status. */
  369. wait_for_single_pid (pid)
  370.      pid_t pid;
  371. {
  372.   pid_t got_pid;
  373.   WAIT status;
  374.   int pstatus;
  375.  
  376.   pstatus = find_status_by_pid (pid);
  377.  
  378.   if (pstatus == PROC_BAD)
  379.     return (127);
  380.  
  381.   if (pstatus != PROC_STILL_ALIVE)
  382.     return (pstatus);
  383.  
  384.   siginterrupt (SIGINT, 1);
  385.   while ((got_pid = WAITPID (pid, &status, 0)) != pid)
  386.     {
  387.       if (got_pid < 0)
  388.     {
  389.       if (errno != EINTR && errno != ECHILD)
  390.         {
  391.           siginterrupt (SIGINT, 0);
  392.           file_error ("wait");
  393.         }
  394.       break;
  395.     }
  396.       else if (got_pid > 0)
  397.         set_pid_status (got_pid, status);
  398.     }
  399.  
  400.   set_pid_status (got_pid, status);
  401.   siginterrupt (SIGINT, 0);
  402.   QUIT;
  403.  
  404.   if (WIFSIGNALED (status))
  405.     return (128 + WTERMSIG (status));
  406.   else
  407.     return (WEXITSTATUS (status));
  408. }
  409.  
  410. /* Wait for all of the shell's children to exit. */
  411. void
  412. wait_for_background_pids ()
  413. {
  414.   pid_t got_pid;
  415.   WAIT status;
  416.  
  417.   /* If we aren't using job control, we let the kernel take care of the
  418.      bookkeeping for us.  wait () will return -1 and set errno to ECHILD 
  419.      when there are no more unwaited-for child processes on both
  420.      4.2 BSD-based and System V-based systems. */
  421.  
  422.   siginterrupt (SIGINT, 1);
  423.  
  424.   /* Wait for ECHILD */
  425.   while ((got_pid = WAITPID (-1, &status, 0)) != -1)
  426.     set_pid_status (got_pid, status);
  427.  
  428.   if (errno != EINTR && errno != ECHILD)
  429.     {
  430.       siginterrupt (SIGINT, 0);
  431.       file_error("wait");
  432.     }
  433.  
  434.   siginterrupt (SIGINT, 0);
  435.   QUIT;
  436. }
  437.  
  438. /* Handle SIGINT while we are waiting for children in a script to exit.
  439.    All interrupts are effectively ignored by the shell, but allowed to
  440.    kill a running job. */
  441. static sighandler
  442. wait_sigint_handler (sig)
  443.      int sig;
  444. {
  445. #if 0
  446.   /* Run a trap handler if one has been defined. */
  447.   maybe_call_trap_handler (sig);
  448. #endif
  449.  
  450. #if !defined (VOID_SIGHANDLER)
  451.   return (0);
  452. #endif /* !VOID_SIGHANDLER */
  453. }
  454.  
  455. /* Wait for pid (one of our children) to terminate.  This is called only
  456.    by the execution code in execute_cmd.c. */
  457. int
  458. wait_for (pid)
  459.      pid_t pid;
  460. {
  461.   int return_val, pstatus;
  462.   pid_t got_pid;
  463.   WAIT status;
  464.   SigHandler *old_sigint_handler;
  465.  
  466.   pstatus = find_status_by_pid (pid);
  467.  
  468.   if (pstatus == PROC_BAD)
  469.     return (0);
  470.  
  471.   if (pstatus != PROC_STILL_ALIVE)
  472.     return (pstatus);
  473.  
  474.   /* If we are running a script, ignore SIGINT while we're waiting for
  475.      a child to exit.  The loop below does some of this, but not all. */
  476.   if (!interactive_shell)
  477.     old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler);
  478.  
  479.   while ((got_pid = WAITPID (-1, &status, 0)) != pid) /* XXX was pid now -1 */
  480.     {
  481.       if (got_pid < 0 && errno == ECHILD)
  482.     {
  483. #if !defined (_POSIX_VERSION)
  484.       status.w_termsig = status.w_retcode = 0;
  485. #else
  486.       status = 0;
  487. #endif /* _POSIX_VERSION */
  488.       break;
  489.     }
  490.       else if (got_pid < 0 && errno != EINTR)
  491.     programming_error ("got errno %d while waiting for %d", errno, pid);
  492.       else if (got_pid > 0)
  493.     set_pid_status (got_pid, status);
  494.     }
  495.  
  496.   set_pid_status (got_pid, status);
  497.  
  498. #if defined (_POSIX_VERSION)
  499.   if (got_pid >= 0)
  500.     reap_zombie_children ();
  501. #endif /* _POSIX_VERSION */
  502.  
  503.   if (!interactive_shell)
  504.     {
  505.       set_signal_handler (SIGINT, old_sigint_handler);
  506.       /* If the job exited because of SIGINT, make sure the shell acts as if
  507.      it had received one also. */
  508.       if (WIFSIGNALED (status) && (WTERMSIG (status) == SIGINT))
  509.     {
  510.       if (maybe_call_trap_handler (SIGINT) == 0)
  511.         (*old_sigint_handler) (SIGINT);
  512.     }
  513.     }
  514.         
  515.   /* Default return value. */
  516.   /* ``a full 8 bits of status is returned'' */
  517.   if (WIFSIGNALED (status))
  518.     return_val = 128 + WTERMSIG (status);
  519.   else
  520.     return_val = WEXITSTATUS (status);
  521.                             
  522.   if (!WIFSTOPPED (status) && WIFSIGNALED (status) &&
  523.       (WTERMSIG (status) != SIGINT))
  524.     {
  525.       fprintf (stderr, "%s", strsignal (WTERMSIG (status)));
  526.       if (WIFCORED (status))
  527.     fprintf (stderr, " (core dumped)");
  528.       fprintf (stderr, "\n");
  529.     }
  530.  
  531.   if (interactive_shell && !subshell_environment)
  532.     {
  533.       if (WIFSIGNALED (status) || WIFSTOPPED (status))
  534.     set_tty_state ();
  535.       else
  536.     get_tty_state ();
  537.     }
  538.  
  539.   return (return_val);
  540. }
  541.  
  542. /* Give PID SIGNAL.  This determines what job the pid belongs to (if any).
  543.    If PID does belong to a job, and the job is stopped, then CONTinue the
  544.    job after giving it SIGNAL.  Returns -1 on failure.  If GROUP is non-null,
  545.    then kill the process group associated with PID. */
  546. int
  547. kill_pid (pid, signal, group)
  548.      pid_t pid;
  549.      int signal, group;
  550. {
  551.   int result;
  552.  
  553.   if (group)
  554.     result = killpg (pid, signal);
  555.   else
  556.     result = kill (pid, signal);
  557.  
  558.   return (result);
  559. }
  560.  
  561. #if defined (_POSIX_VERSION)
  562. static struct termios shell_tty_info;
  563. #else
  564. #  if defined (USG)
  565. static struct termio shell_tty_info;
  566. #  else
  567. static struct sgttyb shell_tty_info;
  568. #  endif /* USG */
  569. #endif /* _POSIX_VERSION */
  570.  
  571. static int got_tty_state = 0;
  572.  
  573. /* Fill the contents of shell_tty_info with the current tty info. */
  574. get_tty_state ()
  575. {
  576.   int tty = open ("/dev/tty", O_RDONLY);
  577.   if (tty != -1)
  578.     {
  579. #if defined (_POSIX_VERSION)
  580.       tcgetattr (tty, &shell_tty_info);
  581. #else
  582. #  if defined (USG)
  583.       ioctl (tty, TCGETA, &shell_tty_info);
  584. #  else
  585.       ioctl (tty, TIOCGETP, &shell_tty_info);
  586. #  endif
  587. #endif
  588.       close (tty);
  589.       got_tty_state = 1;
  590.     }
  591. }
  592.  
  593. /* Make the current tty use the state in shell_tty_info. */
  594. set_tty_state ()
  595. {
  596.   int tty = open ("/dev/tty", O_RDONLY);
  597.   if (tty != -1)
  598.     {
  599.       if (!got_tty_state)
  600.     {
  601.       close (tty);
  602.       return;
  603.     }
  604. #if defined (_POSIX_VERSION)
  605.       tcsetattr (tty, TCSADRAIN, &shell_tty_info);
  606. #else
  607. #  if defined (USG)
  608.       ioctl (tty, TCSETAW, &shell_tty_info);  /* Wait for output, no flush */
  609. #  else
  610.       ioctl (tty, TIOCSETN, &shell_tty_info);
  611. #  endif
  612. #endif
  613.       close (tty);
  614.     }
  615. }
  616.  
  617. /* Give the terminal to PGRP.  */
  618. give_terminal_to (pgrp)
  619.      pid_t pgrp;
  620. {
  621. }
  622.  
  623. /* Stop a pipeline. */
  624. stop_pipeline (async, ignore)
  625.      int async;
  626.      COMMAND *ignore;
  627. {
  628.   already_making_children = 0;
  629. }
  630.  
  631. void
  632. start_pipeline ()
  633. {
  634.   already_making_children = 1;
  635. }
  636.  
  637. /* Print descriptive information about the job with leader pid PID. */
  638. void
  639. describe_pid (pid)
  640.      pid_t pid;
  641. {
  642.   fprintf (stderr, "%d\n", (int) pid);
  643. }
  644.